package com.mia.props;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.mia.craftstudio.CSModel.ModelNode.Attrb;
import com.mia.craftstudio.libgdx.Vector3;
import com.mia.craftstudio.minecraft.ModelMetadata;
import com.mia.props.common.ColorsUtil;
import com.mia.props.common.TileTypeMap;
import net.minecraft.util.AxisAlignedBB;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

public class DecoModelMetadata extends ModelMetadata {
   public String name;
   public int decocraftModelID;
   public int lightLevel = 0;
   public int invX = 0;
   public int invY = 0;
   public boolean walkthrough = false;
   public boolean colorable = false;
   public boolean limitRotation = false;
   public boolean hasVariableRendering = false;
   public boolean spiderweb = false;
   public boolean hideDecobench = false;
   public TabProps tab;
   public TileTypeMap tileType;
   public String sound;
   public String recipe;
   public boolean showOutline;
   public boolean creativeInv;
   public int rotInventory;
   public int rotHeld;
   public String colorPrimary;
   public String colorSecondary;
   public String colorAccentPrimary;
   public String colorAccentSecondary;
   public Map variants;
   public transient int[] resourceCost;
   public transient float itemScale;
   public transient Vector3 itemOffset;
   private transient Map aabbs;
   private static final HashMap fieldMap = new HashMap();

   public DecoModelMetadata() {
      this.tab = TabProps.Main;
      this.tileType = TileTypeMap.Props;
      this.showOutline = true;
      this.creativeInv = true;
      this.rotInventory = 8;
      this.rotHeld = 8;
      this.variants = null;
      this.resourceCost = new int[4];
      this.itemScale = -1.0F;
      this.aabbs = new HashMap();
      if (fieldMap.isEmpty()) {
         Field[] var1 = DecoModelMetadata.class.getFields();
         int var2 = var1.length;

         for(int var3 = 0; var3 < var2; ++var3) {
            Field f = var1[var3];
            fieldMap.put(f.getName(), f);
         }
      }

   }

   public DecoModelMetadata(DecoModelMetadata existingMeta, int newID, JsonObject changes) {
      this.tab = TabProps.Main;
      this.tileType = TileTypeMap.Props;
      this.showOutline = true;
      this.creativeInv = true;
      this.rotInventory = 8;
      this.rotHeld = 8;
      this.variants = null;
      this.resourceCost = new int[4];
      this.itemScale = -1.0F;
      this.aabbs = new HashMap();
      Field foundField;
      if (fieldMap.isEmpty()) {
         Field[] var4 = DecoModelMetadata.class.getFields();
         int var5 = var4.length;

         for(int var6 = 0; var6 < var5; ++var6) {
            foundField = var4[var6];
            fieldMap.put(foundField.getName(), foundField);
         }
      }

      this.craftstudioAssetName = existingMeta.craftstudioAssetName;
      this.craftstudioAssetID = existingMeta.craftstudioAssetID;
      this.scale = existingMeta.scale;
      this.textureOverride = null;
      this.tileParams = new HashMap(existingMeta.tileParams);
      this.csmodel = existingMeta.csmodel;
      this.name = existingMeta.name;
      this.decocraftModelID = newID;
      this.lightLevel = existingMeta.lightLevel;
      this.invX = existingMeta.invX;
      this.invY = existingMeta.invY;
      this.walkthrough = existingMeta.walkthrough;
      this.colorable = existingMeta.colorable;
      this.limitRotation = existingMeta.limitRotation;
      this.hasVariableRendering = existingMeta.hasVariableRendering;
      this.spiderweb = existingMeta.spiderweb;
      this.tab = existingMeta.tab;
      this.tileType = existingMeta.tileType;
      this.sound = existingMeta.sound;
      this.recipe = null;
      this.variants = null;
      this.colorPrimary = existingMeta.colorPrimary;
      this.colorSecondary = existingMeta.colorSecondary;
      this.colorAccentPrimary = existingMeta.colorAccentPrimary;
      this.colorAccentSecondary = existingMeta.colorAccentSecondary;
      this.resourceCost = Arrays.copyOf(existingMeta.resourceCost, 4);
      this.itemScale = existingMeta.itemScale;
      this.itemOffset = existingMeta.itemOffset != null ? new Vector3(existingMeta.itemOffset) : null;
      this.showOutline = existingMeta.showOutline;
      this.creativeInv = existingMeta.creativeInv;
      this.rotInventory = existingMeta.rotInventory;
      this.rotHeld = existingMeta.rotHeld;
      this.faceCulling = existingMeta.faceCulling;
      if (changes != null) {
         Gson gson = (new GsonBuilder()).create();
         Iterator var13 = changes.entrySet().iterator();

         while(var13.hasNext()) {
            Entry entry = (Entry)var13.next();
            foundField = (Field)fieldMap.get(((String)entry.getKey()).intern());
            if (foundField != null) {
               try {
                  foundField.set(this, gson.fromJson((JsonElement)entry.getValue(), foundField.getGenericType()));
               } catch (JsonSyntaxException var9) {
               } catch (IllegalArgumentException var10) {
               } catch (IllegalAccessException var11) {
               }
            }
         }
      }

   }

   public void wrapperCallback() {
      super.wrapperCallback();
      int[] extendBlock = this.wrapper.getExtendBlock(0);
      int width = 1 + extendBlock[3] - extendBlock[0];
      int depth = 1 + extendBlock[5] - extendBlock[2];
      int height = extendBlock[4] - extendBlock[1];
      if (height == 0) {
         ++height;
      }

      if (this.colorPrimary != null) {
         this.wrapper.colorPrimary = ColorsUtil.parseColor(this.colorPrimary);
      }

      if (this.colorSecondary != null) {
         this.wrapper.colorSecondary = ColorsUtil.parseColor(this.colorSecondary);
      }

      if (this.colorAccentPrimary != null) {
         this.wrapper.colorAccentPrimary = ColorsUtil.parseColor(this.colorAccentPrimary);
      }

      if (this.colorAccentSecondary != null) {
         this.wrapper.colorAccentSecondary = ColorsUtil.parseColor(this.colorAccentSecondary);
      }

      this.resourceCost[0] = 3 * width * depth * height;
      int[] pixels = this.csmodel.getTexture().getRGB(0, 0, this.csmodel.getTexture().getWidth(), this.csmodel.getTexture().getHeight(), (int[])null, 0, this.csmodel.getTexture().getWidth());
      long[] total = new long[4];
      int[] var7 = pixels;
      int i = pixels.length;

      for(int var9 = 0; var9 < i; ++var9) {
         int pixel = var7[var9];
         if ((pixel >> 24 & 255) != 0) {
            int r = pixel >> 16 & 255;
            int g = pixel >> 8 & 255;
            int b = pixel & 255;
            total[0] += (long)(r + g + b);
            total[1] += (long)r;
            total[2] += (long)g;
            total[3] += (long)b;
         }
      }

      float[] colorRatios = new float[3];

      for(i = 1; i < 4; ++i) {
         colorRatios[i - 1] = (float)total[i] / (float)total[0];
      }

      if (this.wrapper.colorPrimary != null) {
         colorRatios[0] *= 1.0F + (float)this.wrapper.colorPrimary.getRed() / 255.0F;
         colorRatios[1] *= 1.0F + (float)this.wrapper.colorPrimary.getGreen() / 255.0F;
         colorRatios[2] *= 1.0F + (float)this.wrapper.colorPrimary.getBlue() / 255.0F;
         float divisor = colorRatios[0] + colorRatios[1] + colorRatios[2];
         colorRatios[0] /= divisor;
         colorRatios[1] /= divisor;
         colorRatios[2] /= divisor;
      }

      for(i = 1; i < 4; ++i) {
         this.resourceCost[i] = Math.round((float)this.resourceCost[0] * colorRatios[i - 1]);
      }

      Vector3[] extend = this.wrapper.getExtend(8);
      this.itemScale = Math.min(1.0F / Math.abs(extend[1].y - extend[0].y), Math.min(1.0F / Math.abs(extend[1].x - extend[0].x), 1.0F / Math.abs(extend[1].z - extend[0].z)));
      this.itemOffset = new Vector3(-((extend[0].x + extend[1].x) / 2.0F), -((extend[0].y + extend[1].y) / 35.0F + (extend[0].y < 0.0F ? extend[0].y / 2.0F : 0.0F) + (extend[0].y > 0.0F ? extend[0].y : 0.0F) + (extend[1].y > 0.5F ? extend[1].y / 35.0F : 0.0F) + 0.84F), -((extend[0].z + extend[1].z) / 2.2F));
   }

   public void validate() {
      if (this.textureOverride == null) {
         this.textureOverride = this.getDefaultTextureName();
      }

      if (this.csmodel.getRootNode() != null && this.csmodel.getRootNode().hasAttribute(Attrb.PASSABLEPROPAGATES)) {
         this.walkthrough = true;
      }

   }

   public String getDefaultTextureName() {
      return String.format("%04d_%s.png", this.decocraftModelID, this.name.toLowerCase().replaceAll("[/\\\\:*?\"<>|' ]", "_"));
   }

   public boolean isCraftable(int[] availableResources) {
      return availableResources[0] >= this.resourceCost[0] && availableResources[1] >= this.resourceCost[1] && availableResources[2] >= this.resourceCost[2] && availableResources[3] >= this.resourceCost[3];
   }

   public int compareTo(ModelMetadata o) {
      if (o instanceof DecoModelMetadata) {
         if (this.decocraftModelID < ((DecoModelMetadata)o).decocraftModelID) {
            return -1;
         } else {
            return this.decocraftModelID > ((DecoModelMetadata)o).decocraftModelID ? 1 : 0;
         }
      } else {
         return super.compareTo(o);
      }
   }

   public AxisAlignedBB getBoundingBox(int rotation) {
      AxisAlignedBB aabb = (AxisAlignedBB)this.aabbs.get(rotation);
      if (aabb == null) {
         Vector3[] extend = this.wrapper.getExtend(rotation);
         aabb = AxisAlignedBB.getBoundingBox((double)extend[0].x, (double)extend[0].y, (double)extend[0].z, (double)extend[1].x, (double)extend[1].y, (double)extend[1].z);
         this.aabbs.put(rotation, aabb);
         return aabb;
      } else {
         return aabb;
      }
   }
}
